﻿using AutoMapper;
using BackData;
using Domain;
using Infratructure;
using MD5Hash;
using MediatR;
using Microsoft.AspNetCore.Http;
using Microsoft.IdentityModel.Tokens;
using NLog.LayoutRenderers.Wrappers;
using Server.API.Application.Command;
using Server.API.DTOs;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;

namespace Server.API.Application.Handler
{
    public class LoginHandler : IRequestHandler<LoginCommand, APIResult<UserDTO>>
    {
        private readonly IRepository<UserModel> userway;
        private readonly ILogger<LoginHandler> log;
        private readonly IConfiguration configuration;


        public LoginHandler(IRepository<UserModel> userway, ILogger<LoginHandler> log, IConfiguration configuration)
        {
            this.userway = userway;
            this.log = log;
            this.configuration = configuration;
       
        }
        /// <summary>
        ///登录
        /// </summary>
        /// <param name="request">账号密码</param>
        /// <param name="cancellationToken">取消</param>
        /// <returns>用户信息</returns>
        /// <exception cref="NotImplementedException"></exception>
        public  Task<APIResult<UserDTO>> Handle(LoginCommand request, CancellationToken cancellationToken)
        {
            APIResult<UserDTO> res = new();

            var user = userway.GetAll().FirstOrDefault(x => x.UserName == request.UserName);
            if (user != null)
            {
                if (user.UserPwd == request.UserPwd.GetMD5())
                {
                    
 
                 
                    var result = new UserDTO()
                    {
                        UserName = user.UserName,  // 用户名
                        RealName = user.RealName,  //真实姓名
                        AccountToken = CreateTokenString(user.UserName, user.RealName,TimeSpan.FromMinutes(15)),//创建 短期token
                      //  LongToken = CreateTokenString(user.UserName, user.RealName, TimeSpan.FromDays(15)) //长期Token

                    };
                    log.LogInformation($"用户{request.UserName},登录成功");
                    res.Message = "登录成功";
                    res.Num = StateCode.OK;
                    res.Data = result;
                    return  Task.FromResult(res);

                    //  var expires = DateTime.Now + TimeSpan.FromDays(7);  //长期存储token的过期时间,每次登录刷新
                }
                else
                {
                    res.Message = "密码错误";
                    res.Num = StateCode.Fail;
                    return Task.FromResult(res);
                }
            }
            else
            {
                res.Message = "用户名不存在";
                res.Num = StateCode.Fail;
                return Task.FromResult(res);
            }
        }

        /// <summary>/// 生成 JWT Token（令牌）/// </summary>/// <returns></returns>
        private string CreateTokenString(string UserName, string RealName, TimeSpan expiry)
        {
            //私钥
            var secretByte = Encoding.UTF8.GetBytes(configuration["JwtSettings:secretByte"]);
            //荷载
            var claims = new[]
            {
                new Claim("UserName", UserName), // 用户名
                new Claim("RealName", RealName) // 真实姓名
            };
            // 非对称加密
            var signingKey = new SymmetricSecurityKey(secretByte);
            // 使用256 生成数字签名
            var signingCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256);
            // 生成Token
            var token = new JwtSecurityToken(
                issuer: configuration["JwtSettings:Issuer"],
                audience: configuration["JwtSettings:Audience"],
                expires: DateTime.UtcNow.Add(expiry), // 规定时间后过期
                signingCredentials: signingCredentials,
                claims: claims  //载荷
            );
            // 生成token 字符串
            var strToken = new JwtSecurityTokenHandler().WriteToken(token);
            return strToken;
        }
    }
}
